home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / dflat_r_.arc / HUFFC.C < prev    next >
Text File  |  1991-10-02  |  2KB  |  104 lines

  1. /* ------------------- huffc.c -------------------- */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #define INCLUDE_COMPRESS_HELPFILE
  7.  
  8. #include "htree.h"
  9.  
  10. static void compress(FILE *, int, int);
  11. static void outbit(FILE *fo, int bit);
  12.  
  13. void main(int argc, char *argv[])
  14. {
  15.     FILE *fi, *fo;
  16.     int c;
  17.     BYTECOUNTER bytectr = 0;
  18.     int freqctr = 0;
  19.  
  20.     if (argc < 3)   {
  21.         printf("\nusage: huffc infile outfile");
  22.         exit(1);
  23.     }
  24.  
  25.     if ((fi = fopen(argv[1], "rb")) == NULL)    {
  26.         printf("\nCannot open %s", argv[1]);
  27.         exit(1);
  28.     }
  29.     if ((fo = fopen(argv[2], "wb")) == NULL)    {
  30.         printf("\nCannot open %s", argv[2]);
  31.         fclose(fi);
  32.         exit(1);
  33.     }
  34.  
  35.     ht = calloc(256, sizeof(struct htree));
  36.  
  37.     /* - read the input file and count character frequency - */
  38.     while ((c = fgetc(fi)) != EOF)   {
  39.         c &= 255;
  40.         if (ht[c].cnt == 0)   {
  41.             freqctr++;
  42.             ht[c].ch = c;
  43.         }
  44.         ht[c].cnt++;
  45.         bytectr++;
  46.     }
  47.  
  48.     /* --- write the byte count to the output file --- */
  49.     fwrite(&bytectr, sizeof bytectr, 1, fo);
  50.  
  51.     /* --- write the frequency count to the output file --- */
  52.     fwrite(&freqctr, sizeof freqctr, 1, fo);
  53.  
  54.     /* -- write the frequency array to the output file -- */
  55.     for (c = 0; c < 256; c++)   {
  56.         if (ht[c].cnt > 0)    {
  57.             fwrite(&ht[c].ch, sizeof(char), 1, fo);
  58.             fwrite(&ht[c].cnt, sizeof(BYTECOUNTER), 1, fo);
  59.         }
  60.     }
  61.  
  62.     /* ---- build the huffman tree ---- */
  63.     buildtree();
  64.  
  65.     /* ------ compress the file ------ */
  66.     fseek(fi, 0L, 0);
  67.     while ((c = fgetc(fi)) != EOF)
  68.         compress(fo, (c & 255), 0);
  69.     outbit(fo, -1);
  70.     fclose(fi);
  71.     fclose(fo);
  72. }
  73.  
  74. /* ---- compress a character value into a bit stream ---- */
  75. static void compress(FILE *fo, int h, int child)
  76. {
  77.     if (ht[h].parent != -1)
  78.         compress(fo, ht[h].parent, h);
  79.     if (child)  {
  80.         if (child == ht[h].right)
  81.             outbit(fo, 0);
  82.         else if (child == ht[h].left)
  83.             outbit(fo, 1);
  84.     }
  85. }
  86.  
  87. static char out8;
  88. static int ct8;
  89.  
  90. /* -- collect and write bits to the compressed output file -- */
  91. static void outbit(FILE *fo, int bit)
  92. {
  93.     if (ct8 == 8 || bit == -1)  {
  94.         while (ct8 < 8)    {
  95.             out8 <<= 1;
  96.             ct8++;
  97.         }
  98.         fputc(out8, fo);
  99.         ct8 = 0;
  100.     }
  101.     out8 = (out8 << 1) | bit;
  102.     ct8++;
  103. }
  104.